{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Data exploration workflow with diffprivlib"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "\n",
    "import numpy as np\n",
    "import diffprivlib as dp\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Data and differential privacy set-up"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We begin by initialising a `BudgetAccountant` to track the privacy spend of our exploration. By using the `set_default()` method, this accountant will be used by default in all diffprivlib calls."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "acc = dp.BudgetAccountant(1, 0)\n",
    "acc.set_default()\n",
    "\n",
    "# Our default epsilon value for this exploration\n",
    "eps = 0.04"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We will use the Covertype dataset for this example. We can load is using `sklearn`. For the purpose of this exploration, we will use a numerical encoding of the \"Wilderness Area\" and \"Soil Type\" attributes. This will simplify visualisations later on."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.datasets import fetch_covtype\n",
    "\n",
    "dataset = fetch_covtype()\n",
    "data, labels = dataset.data, dataset.target\n",
    "\n",
    "# Switch from one-hot encoding to numerical encoding for Wilderness Area and Soil Type\n",
    "data = np.concatenate((\n",
    "    data[:, :-44], \n",
    "    (data[:, -44:-40] * np.arange(0, 4)).sum(axis=1)[:, np.newaxis],\n",
    "    (data[:, -40:] * np.arange(0, 40)).sum(axis=1)[:, np.newaxis]\n",
    "), axis=1)\n",
    "\n",
    "n_examples = data.shape[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To assist our exploration, we will also specify the column names, and the ranges of each column. In this case, the ranges are assumed to be public knowledge, and therefore are not required to be calculated on the data. If the range is not known, it is common to search using a differentially private histogram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "col_names = [\"Elevation\", \"Aspect\", \"Slope\", \"H-Distance To Hydrology\", \n",
    "             \"V-Distance To Hydrology\", \"H-Distance To Roadways\", \n",
    "             \"Hillshade 9am\", \"Hillshade Noon\", \"Hillshade 3pm\", \n",
    "             \"H-Distance To Fire Points\", \"Wilderness Area\", \"Soil Type\"]\n",
    "\n",
    "ranges = [(1000.0, 4000.0), (0, 360), (0, 66), (0, 1000.0), (0, 1000.0),\n",
    "  (10, 10000.0), (0, 255), (0, 255), (0, 255), (10, 10000.0), (0, 3), (0, 39)]\n",
    "\n",
    "assert len(col_names) == len(ranges)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Initial exploration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `histogram` function is a useful tool to visualise the data in a differentially private way. The syntax is the same as the corresponding function in NumPy, with the addition of an `epsilon` parameter. Also, to preserve differential privacy, we must specify the `range` of the histogram.\n",
    "\n",
    "In this first example, we plot the number of examples of each of the Covertype labels, 1‒7. The counts are not exact due to differential privacy, but give a good approximation of the true values. We can see that almost 50% of examples in the dataset are associated with the label \"2\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 360x252 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1, figsize=(5,3.5))\n",
    "\n",
    "ax.bar(np.linspace(1, 7, 7), dp.tools.histogram(labels, epsilon=eps, bins=7, range=(1, 8))[0] / n_examples)\n",
    "ax.set_title(\"Label counts\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also plot the distribution of features in the dataset using `histogram`. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 1152x864 with 12 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axs = plt.subplots(3, 4, sharey=True, figsize=(16, 12))\n",
    "fig.subplots_adjust(hspace=0.35)\n",
    "\n",
    "for i in range(len(col_names)):\n",
    "    ax = axs.flat[i]\n",
    "    ax.set_title(col_names[i])\n",
    "    _range = ranges[i]\n",
    "    n_bins = 10\n",
    "    \n",
    "    # Wilderness Area and Soil Type need special config\n",
    "    if i >= 10:\n",
    "        _range = (0, _range[1] + 1)\n",
    "        n_bins = _range[1]\n",
    "\n",
    "    bar_width = (_range[1] - _range[0]) / n_bins * 0.9\n",
    "    \n",
    "    hist, bins = dp.tools.histogram(data[:, i], bins=n_bins, range=_range, epsilon=eps)\n",
    "    ax.bar(bins[:-1] + np.diff(bins), hist / n_examples, width=bar_width)\n",
    "    ax.set_ylim(0, 1)\n",
    "\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "After our initial exploration, now is a good time to examine our budget spend, confirming that we have executed 13 queries thus far."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(epsilon=0.5199999999999999, delta=0.0)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc.total()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "13"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "len(acc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Additional exploration"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also use 2-dimensional histograms to extract more information in a differentially private way. In this example, we can plot the distribution of a feature with respect to each label."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Js4999y/65o5e/ZsNtxwQxYuXMj3vvc9jj76aL797W8DsGLFCi6++GIOP/xwAG688Ua++MUvcscdd3D33Xfz4x//mMcee4zPfOYzXH311dx0001MnDiRL3zhC63aXVJbswulJEnSIHbDDTdw6KGHMmTIELbcckve+ta3Mn/+fA444ABOOOEEXnjhBS6//HImT57MhhtuyJVXXsmtt97KJZdcAsBTTz3FH//4R4YOHcruu+/e1DPYRo8ezYgRI7j55pt5+OGH2XXXXRkxYgQAu+++O9tuuy0Ahx56KDfccAPDhg3jjjvu4C1veQtQJJSTJk1q0R6R2psJnCRJ0gC34447rky4mjVs2DCmTJnCFVdcwZw5c5gxYwZQ3E/3xS9+kf333/9ly8+bN4+NNtqo6fKPPfZYLrzwQh566CGOPvroldN7PgogIshM9t13Xy666KI12gZpILILpSRJ0gC3zz778MILL3D++eevnHbrrbdy/fXXs/feezNnzhyWL1/Oo48+yq9+9St23313AKZPn843v/lNrr/+eqZOnQrA/vvvz1e+8hWWLl0KwB/+8AeeffbZPmNYf/31V64DMG3aNC6//HLmz5//smTwxhtvZMmSJaxYsYI5c+aw1157seeee/LrX/+axYsXA/Dss8/26wiaUjsxgZMkSRrgIoKf/OQnXH311Wy33XbsuOOOnHrqqWy11VZMmzaNnXfemTe/+c3ss88+nH322Wy11VYA7Lfffvzyl7/kHe94B0OHDgWKK2fjxo1j/PjxvOlNb+LDH/4wy5Yt6zOGmTNnsvPOO3PYYYcBMHToUN72trdxyCGHMGTIkJXL7bbbbhx//PGMHTuWMWPGMG3aNDbffHMuvPBCDj30UHbeeWcmTZrE73//+xbsKan9RWbWHcPLTJw4MRcsWFB3GJIqFhG/y8yJdcexLmyfpIFnoLZNd955J2PHjq0pouasWLGC8ePH88Mf/pDtt98eKLphfu5zn+PSSy9d63I7YdvXxeenv6vyMk+as/b7W62xurbJK3CSJEnqV3fccQevf/3refvb374yeZPUHAcxkSRJUr8aN24c99xzz99NnzJlClOmTOn/gKQO4hU4SZIkSeoQXoGTJEmSOsSw4SfWHYJq5hU4SZIkSeoQJnCSJEmS1CHsQilJkiQARp/y80rLu3f2O/tc5uijj+bSSy9l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\n",
      "text/plain": [
       "<Figure size 1080x288 with 3 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, axs = plt.subplots(1, 3, figsize=(15, 4), sharey=True)\n",
    "n_bins = 10\n",
    "\n",
    "# Columns of the dataset we want to plot\n",
    "cols = (1, 3, 8)\n",
    "\n",
    "for _i, col in enumerate(cols):\n",
    "    ax = axs.flat[_i]\n",
    "    ax.set_title(col_names[col])\n",
    "    width = (ranges[col][1] - ranges[col][0]) / n_bins * 0.9\n",
    "\n",
    "    hist, bins, _ = dp.tools.histogram2d(data[:, col], labels, epsilon=eps, bins=(n_bins, 7), \n",
    "                                             range=(ranges[col], (1, 8)))\n",
    "    cum_sum = np.zeros_like(hist[:, 0])\n",
    "\n",
    "    for i in range(hist.shape[1]):\n",
    "        ax.bar(bins[:-1] + np.diff(bins), hist[:, i] / n_examples, bottom=cum_sum, label=str(i+1), width=width)\n",
    "        cum_sum += hist[:, i] / n_examples\n",
    "        \n",
    "ax.legend(title=\"Cover type\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With some extra effort, we can also produce 2-dimensional histograms to show correlation between features."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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1iAu22Q1ERERNGjQgF69etG4ceNkk3kk9Q77efPm0alTJ/LmzUuFChUIDQ1lzZo1AISGhnLTTTcBTganefPmUblyZZYuXcpnn30GOGnshg4d6jPnZ548eYiNjaVChQpUqFDhsvnnz5/n4MGDXHfddZQvX96vbT59+jRz5sxh/PjxlClThqlTp/rVzlurVq080/Xq1fM8659UGr7ly5fTrFkzihQpAkCzZs1YtGgRd955pyfVH+BJ9Rf/pFagsnUATS+jH10atGX3GdskaMs2aWf79u0sXLiQUaNG0adPHx588EG6d+/ODTfc4Pcy9u7d6wkAkDBdXeKUdKtXr+bgwYNcf/315MqV67L63i5evEiVKlXo2bMn33zzDSEhIQnmnz9/npo1a3LfffexbNkyT3BKysaNGxk/fjwLFy7k7rvv5q233vJkud+2bRsdO3b02W758uVcf/31PuedO3eOKVOm8N5773n2ha80fMmVJ5Xq70rYIbwx6SBnzpz885//5IsvvmDFihXs2rWLcuXKeUaQGemDDz6gZs2afPjhh9x7773ExcWxdu1a2rVrB8Czzz5Ljx49ePrpp4mMjOTkyZPMmjWLAQMGXLast99+m/r161OxYkU2b97MqFGjErwipFKlSj6TpkRFRSUZPAEee+wxGjVqxO23357m238lgjoCFZG7gfeAnMB4VR2RaP5TwEPAeSAO6Kmqv7vzugEvuFVfVtVJGJOFHT16lOnTpzNx4kTy5MnDhAkTqFGjht/tk0s956u8aNGiHDlyhPPnz5MrV64kU9UtXryYf//739x5550MHjyYe+65h3r16tGpUyfP/H79+hESEsKBAwdo37491157LQMHDrxsWV26dOHcuXOMGzeOZcuW0aNHD1q2bOkZBQcyAh02bBhxcXGMGzcuxX1RpkwZli9fnqD8zjvvTDbV35UI2ghURHICo4GWQBXgfhGpkqjaz0CEqtYAZgMj3bZFgBeB+kA94EURKRysvhoTbF26dKF27drs3r2byZMn8/3339O1a9fLXsuRnMjISKZPn86ZM2fYvXs30dHR1KtXj7p16xIdHc3u3bs5e/Ys06dPJzIyEhGhcePGzJ49G0iYxs5brVq1mDp1KhcvXqRDhw6EhYXx2WefeS4W1apVi8mTJwPw1FNPcfz4cTZv3kydOnUuW1aJEiV45pln2LRp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\n",
      "text/plain": [
       "<Figure size 360x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1, figsize=(5, 4))\n",
    "col1, col2 = (3, 5)\n",
    "\n",
    "n_bins = 10\n",
    "\n",
    "ax.set_title(col_names[col1] + \" v \\n\" + col_names[col2])\n",
    "width = (ranges[col1][1] - ranges[col1][0]) / n_bins * 0.9\n",
    "\n",
    "hist, bins, _ = dp.tools.histogram2d(\n",
    "    data[:, col1], \n",
    "    (data[:, col2] > 1000).astype(int) + (data[:, col2] > 2000) + (data[:, col2] > 3000) + (data[:, col2] > 4000), \n",
    "    epsilon=eps, bins=(n_bins, 5), range=(ranges[col1], (0, 5))\n",
    ")\n",
    "legends = [\"<= 1000\", \"> 1000 && <= 2000\", \"> 2000 && <= 3000\", \"> 3000 && <= 4000\", \"> 4000\"]\n",
    "\n",
    "cum_sum = np.zeros_like(hist[:, 0])\n",
    "\n",
    "for i in range(hist.shape[1]):\n",
    "    ax.bar(bins[:-1] + np.diff(bins), hist[:, i] / n_examples, bottom=cum_sum, label=legends[i], width=width)\n",
    "    cum_sum += hist[:, i] / n_examples\n",
    "\n",
    "ax.set_xlabel(col_names[col1])\n",
    "ax.set_ylabel(\"Frequency\")\n",
    "ax.legend(title=col_names[col2])\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Colour maps"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also use the 2-dimensional histogram to plot colour maps of the data. This allows us to examine correlations between features."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 360x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "col1, col2 = (1, 3)\n",
    "\n",
    "hist, bins_y, bins_x = dp.tools.histogram2d(data[:, col1], data[:, col2], epsilon=eps, \n",
    "                                            range=(ranges[col1], ranges[col2]))\n",
    "\n",
    "fig, ax = plt.subplots(1, 1, figsize=(5, 4))\n",
    "c = ax.pcolormesh(bins_y, bins_x, hist / n_examples, cmap='Blues')\n",
    "ax.set_ylabel(col_names[col1])\n",
    "ax.set_xlabel(col_names[col2])\n",
    "fig.colorbar(c, ax=ax)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Other queries"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Diffprivlib includes a number of simple statistical functions to examine the data in more detail. These include `mean`, `var`, `sum` and `count_nonzero` functions.  They can be useful in querying more specific information than can be portrayed by histograms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2959.413492430157"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.mean(data[:, 0], bounds=ranges[0], epsilon=eps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "76507.10941871432"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.var(data[:, 0], bounds=ranges[0], epsilon=eps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`count_nonzero` is useful for counting more specific information than is required from a histogram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "0.49394160533689496"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.count_nonzero(data[:, 0] >= 3000, epsilon=eps) / n_examples"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also get label-specific information by indexing the `data` array appropriately."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "3128.5443965699988"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dp.tools.mean(data[labels==1, 0], bounds=ranges[0], epsilon=eps)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Total privacy loss"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Having completed our initial exploration, we can compute the total privacy loss from the accountant."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(epsilon=0.8800000000000002, delta=0.0)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc.total()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And we can also compute the remaining budget to be spent on subsequent queries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(epsilon=0.11999999999999988, delta=0.0)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "acc.remaining()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
